﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Web.Security;
using Beeldbankmvc.Code;
using Beeldbankmvc.Helpers;
using Beeldbankmvc.Models;
using Beeldbankmvc.ViewModels;
using System.Configuration;
using System.Web.UI;

namespace Beeldbankmvc.Controllers
{
	[HandleErrorWithELMAH]
	public class SearchController : Controller
	{
		SearchQueryRepository searchQueryRepository = new SearchQueryRepository();

		BeeldbankLinqDataContext beeldBankDB = new BeeldbankLinqDataContext();

		UserRepository userRepository = new UserRepository();

		//
		// GET: /
		//
		// cache the search query for a day
        [OutputCache(Duration = (3600 * 24), VaryByParam = "*", VaryByCustom = "IsLoggedIn", Location = OutputCacheLocation.Server)]
		public ActionResult Index(string SearchCriteria, bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration, bool? onlyMyItems, byte? OrderBy, bool? fromDateCheck, bool? toDateCheck, string fromDate, string toDate, int? page, int? displayMode, int? collectionId, int? statusId, bool? showInternalItems, int? RegioFacet, int? TechniekFacet, int? RiviergebiedFacet, int? ProjectFacet)
		{
			// Set search variables based on query string or default values
			#region Set search variables
			
			// Bypass check if dates should be taken into account for the search: this is 'true' by default
			if ((fromDate != null) && (toDate != null))
			{
				fromDateCheck = true;
				toDateCheck = true;
			}

			searchParameters searchParameters = new searchParameters() { SearchCriteria = SearchCriteria, displayMode = displayMode, fromDate = fromDate, fromDateCheck = fromDateCheck, toDate = toDate, toDateCheck = toDateCheck, OrderBy = OrderBy, page = page, typeAnaloog = typeAnaloog, typeDigitaal = typeDigitaal, typeVideoAnimation = typeVideoAnimation, typeMapIllustration = typeMapIllustration, onlyMyItems = onlyMyItems, collectionId = collectionId, statusId = statusId, showInternalItems = showInternalItems, RegioFacet = RegioFacet, TechniekFacet = TechniekFacet, RiviergebiedFacet = RiviergebiedFacet, ProjectFacet = ProjectFacet };
			TempData["resultSearchCriteria"] = searchParameters;

			string typeString = SetTypeString(typeAnaloog, typeDigitaal, typeVideoAnimation, typeMapIllustration);

			DateTime? from = null;
			if (fromDateCheck != null && !String.IsNullOrEmpty(fromDate))
				from = Convert.ToDateTime(fromDate);
			//else
			//	from = Convert.ToDateTime("1-1-1900");

			DateTime? to = null;
			if (toDateCheck != null && !String.IsNullOrEmpty(toDate))
				to = Convert.ToDateTime(toDate);
			//else
			//	to = DateTime.Now;

			// Default order by is on 'Datum aflopend'
			byte? orderBy = 7;
			if (OrderBy != null)
				orderBy = OrderBy;

			// If no SearchCriteria is given a default must be passed or else
			// the stored procedure will run in an indefinite loop
			String searchString = "";
			if (!String.IsNullOrEmpty(SearchCriteria))
				searchString = SearchCriteria;

			// If SearchString is empty, then an orderBy Relevance will not work
			if ((searchString == "") && (orderBy == 3))
				orderBy = 7;
			
			int? selectedPage = 0;
			if (page != null)
				selectedPage = page;

			int? aantalResultaten = SetNrResults(displayMode);

			if (collectionId == null)
				collectionId = 0;
			if (RegioFacet == null)
				RegioFacet = 0;
			if (TechniekFacet == null)
				TechniekFacet = 0;
			if (RiviergebiedFacet == null)
				RiviergebiedFacet = 0;
			if (ProjectFacet == null)
				ProjectFacet = 0;

			int IDOnlyQuery = 0;
			Regex IDpattern = new Regex("ID[0-9]*\\Z");
			if (SearchCriteria != null && IDpattern.IsMatch(SearchCriteria))
			{
				IDOnlyQuery = 1;
				searchString = searchString.Substring(2, searchString.Length - 2);
			}
			#endregion

			// Code useful for debugging the stored procedure
			#region Debug code

			/* example
				USE [BeeldBankVenW]
				GO

				DECLARE	@return_value int,
						@RowsReturned int

				EXEC	@return_value = [dbo].[BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC]
						@SearchCriteria = N'water',
						@TypeList = N'16 19 20 24',
						@dtFrom = N'1900-1-1',
						@dtTo = N'2011-5-17',
						@PageIndex = 0,
						@PageSize = 20,
						@OrderBy = 6,
						@CollectionId = 0,
						@StatusId = 11911,
						@RowsReturned = @RowsReturned OUTPUT,
						@ShowAll = 0,
						@ShowMyItems = '',
						@ShowMyItemsID = '',
						@RegioFacet = 0,
						@TechniekFacet = 0,
						@RiviergebiedFacet = 0,
						@ProjectFacet = 0,
						@StatusId = 11911

				SELECT	@RowsReturned as N'@RowsReturned'

				SELECT	'Return Value' = @return_value

				GO
			 */

			// build this string for debugging
			//String spExec = "EXEC	@return_value = [dbo].[BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC]" +
			//        "@SearchCriteria = N'" + searchString + "'," +
			//        "@dtFrom = '" + from.ToString() + "'," +
			//        "@dtTo = '" + to.ToString() + "'," +
			//        "@TypeList = '" + typeString + "'," +
			//        "@PageIndex = 0," +
			//        "@PageSize = 10," +
			//        "@OrderBy = " + orderBy + "," +
			//        "@CollectionId = " + collectionId + "," +
			//        "@StatusId = " + StatusId + "," +
			//        "@RowsReturned = @RowsReturned OUTPUT," +
			//        "@RegioFacet = " + RegioFacet + "," +
			//        "@TechniekFacet = " + TechniekFacet + "," +
			//        "@RiviergebiedFacet = " + RiviergebiedFacet + "," +
			//        "@ProjectFacet = " + ProjectFacet + ",";
			#endregion

			// Rights section for different search results
			#region Rights section
			// User for edit rights and/or be able to see internal images
			MembershipUser currentUser = Membership.GetUser();
			String currentUserName = "";
			String currentUserEmail = "";
			
			// User rights based search options
			int RWSonly = 0;
			string ShowMyItems = "";
			string ShowMyItemsID = "";
			int ShowAll = 0;
			if (currentUser != null)
			{
				currentUserName = currentUser.UserName;
				currentUserEmail = currentUser.Email;

				// @RWS.nl users get to see internal images
				if (currentUser.Email.EndsWith("@rws.nl") && showInternalItems != null && Convert.ToBoolean(showInternalItems) == true)
					RWSonly = 1;
				
				// Show only this persons items
				if (onlyMyItems != null && Convert.ToBoolean(onlyMyItems) == true)
				{
					if (Roles.IsUserInRole("Administrator"))
						ShowAll = 1;
					else
					{
						ShowMyItems = currentUser.UserName;
						ShowMyItemsID = userRepository.FindOnesGuidByName(currentUser.UserName).ToString();
					}
				}
			}
			#endregion

			// Get multiple results from search stored procedure
			#region Execute dynamic search stored procedure
            IMultipleResults multipleResults = null;
            if (
                (searchString == "") &&
                (collectionId == 0) &&
                (typeString == "16 19 20 24") &&
                (RegioFacet == 0) &&
                (TechniekFacet == 0) &&
                (RiviergebiedFacet == 0) &&
                (ProjectFacet == 0) &&
                (ShowMyItems == "") &&
                (IDOnlyQuery == 0) &&
                (RWSonly == 0) &&
                (ShowAll == 0) &&
                (from == null) &&
                (to == null)
                )
    			multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC_FAST(searchString, typeString, from, to, selectedPage, aantalResultaten, orderBy, collectionId, statusId, ref aantalResultaten, IDOnlyQuery, RWSonly, ShowAll, ShowMyItems, ShowMyItemsID, RegioFacet, TechniekFacet, RiviergebiedFacet, ProjectFacet);
            else
    			multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC(searchString, typeString, from, to, selectedPage, aantalResultaten, orderBy, collectionId, statusId, ref aantalResultaten, IDOnlyQuery, RWSonly, ShowAll, ShowMyItems, ShowMyItemsID, RegioFacet, TechniekFacet, RiviergebiedFacet, ProjectFacet);

            List<BEELDBANK_MEDIAOBJECT> Mediaobjects = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_REGIO> RegioFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_REGIO>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_TECHNIEK> TechniekFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_TECHNIEK>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_RIVIERGEBIED> RivierGebiedFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_RIVIERGEBIED>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_PROJECT> ProjectFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_PROJECT>().ToList();
			List<BEELDBANK_TYPE> TypeFacets = multipleResults.GetResult<BEELDBANK_TYPE>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_RESULT> YearFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_RESULT>().ToList();
            List<BEELDBANK_COLLECTION> ThemaFacets = multipleResults.GetResult<BEELDBANK_COLLECTION>().ToList();
            
            string rowsReturned = "";
            if (
                (searchString == "") &&
                (collectionId == 0) &&
                (typeString == "16 19 20 24") &&
                (RegioFacet == 0) &&
                (TechniekFacet == 0) &&
                (RiviergebiedFacet == 0) &&
                (ProjectFacet == 0) &&
                (ShowMyItems == "") &&
                (IDOnlyQuery == 0) &&
                (RWSonly == 0) &&
                (ShowAll == 0) &&
                (from == null) &&
                (to == null)
                )
                rowsReturned = multipleResults.GetResult<int>().ToList().First().ToString();
            else
                rowsReturned = multipleResults.ReturnValue.ToString();
            #endregion

			// Save the search for statistics
			#region Save search
			// save this search query, but only when at least one record was found and when it is not a crawler
            if (!String.IsNullOrEmpty(searchString) && Convert.ToInt32(rowsReturned) > 0 && (Request.Browser.Crawler == false)) // && (FacetsResults[0].results > 0)
			{
				BEELDBANK_ZOEKACTIELOG logThisQuery = new BEELDBANK_ZOEKACTIELOG();
                logThisQuery.AantalResultaten = Convert.ToInt32(rowsReturned); //FacetsResults[0].results;
				logThisQuery.Begindatum = fromDateCheck;
				logThisQuery.Einddatum = toDateCheck;
				logThisQuery.Criteria = searchString.Substring(0, 1).ToUpper() + searchString.Substring(1, searchString.Length - 1);
				logThisQuery.ZoekType = typeString;
				logThisQuery.ZoekDatum = DateTime.Now;

				searchQueryRepository.Add(logThisQuery);
				searchQueryRepository.Save();
			}
			#endregion

			// Save all ID's of this search page to be able to navigate trough the results in detail mode
			#region In memory results index
			String resultIdList = "";
			foreach (var mediaObject in Mediaobjects)
			{
				resultIdList += mediaObject.Id + ",";
			}
			TempData["resultIdList"] = resultIdList.TrimEnd(',');
			TempData["resultIdType"] = "Search";
			#endregion

			// Fill the results view model
			#region Fill results view model
			var viewModel = new SearchViewModel()
			{
				selectedCollectionId = collectionId,
				selectedStatusId = statusId,
                NumberOfResults = Convert.ToInt32(rowsReturned), //multipleResults.ReturnValue, //FacetsResults[0].results,
				mediaobjects = Mediaobjects.ToList(),
				currentUserName = currentUserName,
				currentUserEmail = currentUserEmail,

				RegioFacets = RegioFacets.ToList(),
				TechniekFacets = TechniekFacets.ToList(),
				RivierGebiedFacets = RivierGebiedFacets.ToList(),
				ProjectFacets = ProjectFacets.Where(p => p.Publicatie.Equals(ConfigurationManager.AppSettings["publicationName"])).ToList(),
				TypeFacets = TypeFacets.ToList(),
				YearFacets = YearFacets.ToList(),
				ThemaFacets = ThemaFacets.ToList(),

				RegioFacetsAll = beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_REGIOs.ToList(),
				TechniekFacetsAll =beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_TECHNIEKs.ToList(),
				RivierGebiedFacetsAll = beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_RIVIERGEBIEDs.ToList(),
				ProjectFacetsAll = beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_PROJECTs.ToList(),
				TypeFacetsAll = beeldBankDB.BEELDBANK_TYPEs.ToList(),
				YearFacetsAll = Tools.generateYearList(), // TODO: still have to generate a list of all years
				ThemaFacetsAll = beeldBankDB.BEELDBANK_COLLECTIONs.ToList(),
			};
			#endregion

			return View(viewModel);
		}

        //
        // GET: /
        //
        // cache the search query for a day
        [OutputCache(Duration = (3600 * 24), VaryByParam = "*", VaryByCustom = "IsLoggedIn", Location = OutputCacheLocation.Server)]
        public ActionResult ZoekplaatjeIndex(string SearchCriteria, byte? OrderBy, int? page, int? displayMode, int? statusId)
        {
            // Set search variables based on query string or default values
            #region Set search variables

            searchParameters searchParameters = new searchParameters() { SearchCriteria = SearchCriteria, displayMode = displayMode, OrderBy = OrderBy, page = page };
            TempData["resultSearchCriteriaZP"] = searchParameters;

            // Default order by is on 'Datum aflopend'
            byte? orderBy = 7;
            if (OrderBy != null)
                orderBy = OrderBy;

            // If no SearchCriteria is given a default must be passed or else
            // the stored procedure will run in an indefinite loop
            String searchString = "";
            if (!String.IsNullOrEmpty(SearchCriteria))
                searchString = SearchCriteria;

            // If SearchString is empty, then an orderBy Relevance will not work
            if ((searchString == "") && (orderBy == 3))
                orderBy = 7;

            int? selectedPage = 0;
            if (page != null)
                selectedPage = page;

            int? aantalResultaten = SetNrResults(displayMode);

            #endregion

            // Rights section for different search results
            #region Rights section
            // User for edit rights and/or be able to see internal images
            MembershipUser currentUser = Membership.GetUser();
            String currentUserName = "";
            String currentUserEmail = "";

            // User rights based search options
            if (currentUser != null)
            {
                currentUserName = currentUser.UserName;
                currentUserEmail = currentUser.Email;
            }
            #endregion

            // Get multiple results from search stored procedure
            #region Execute dynamic search stored procedure
            IMultipleResults multipleResults = null;
            if (searchString == "")
                multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC_FAST_ZP(searchString, selectedPage, aantalResultaten, orderBy, ref aantalResultaten);
            else
                multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC_ZP(searchString, selectedPage, aantalResultaten, orderBy, ref aantalResultaten);

            List<BEELDBANK_MEDIAOBJECT> Mediaobjects = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT>().ToList();

            string rowsReturned = "";
            if (searchString == "")
                rowsReturned = multipleResults.GetResult<int>().ToList().First().ToString();
            else
                rowsReturned = multipleResults.ReturnValue.ToString();
            #endregion
            
            // Save all ID's of this search page to be able to navigate trough the results in detail mode
            #region In memory results index
            String resultIdList = "";
            foreach (var mediaObject in Mediaobjects)
            {
                resultIdList += mediaObject.Id + ",";
            }
            TempData["resultIdListZP"] = resultIdList.TrimEnd(',');
            TempData["resultIdTypeZP"] = "Search";
            #endregion

            // Fill the results view model
            #region Fill results view model
            var viewModel = new SearchViewModel()
            {
                NumberOfResults = Convert.ToInt32(rowsReturned),
                mediaobjects = Mediaobjects.ToList(),
                currentUserName = currentUserName,
                currentUserEmail = currentUserEmail,
            };
            #endregion

            return View(viewModel);
        }

        //
		// GET: /SearchInternal/
		//
		[Authorize(Roles = "Administrator, Beheerder, EindRedacteur, Gebruiker")]
		public ActionResult SearchInternal(string SearchCriteria, bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration, bool? onlyMyItems, byte? OrderBy, bool? fromDateCheck, bool? toDateCheck, string fromDate, string toDate, int? page, int? displayMode, int? collectionId, int? statusId, bool? showInternalItems, int? RegioFacet, int? TechniekFacet, int? RiviergebiedFacet, int? ProjectFacet)
		{
			return RedirectToAction("Index", "Search",
				new {
					SearchCriteria = SearchCriteria,
					typeAnaloog = typeAnaloog,
					typeDigitaal = typeDigitaal,
					typeVideoAnimation = typeVideoAnimation,
					typeMapIllustration = typeMapIllustration,
					onlyMyItems = onlyMyItems, 
					OrderBy = OrderBy, 
					fromDateCheck = fromDateCheck, 
					toDateCheck = toDateCheck, 
					fromDate = fromDate, 
					toDate = toDate, 
					page = page, 
					displayMode = displayMode,
					collectionId = collectionId,
					statusId = statusId, 
					showInternalItems = showInternalItems, 
					RegioFacet = RegioFacet, 
					TechniekFacet = TechniekFacet, 
					RiviergebiedFacet = RiviergebiedFacet, 
					ProjectFacet = ProjectFacet});
		}
		
		//
		// GET: /Search/FieldSearch
		//
		[Authorize(Roles = "Administrator, Beheerder, EindRedacteur")]
		public ActionResult FieldSearch(string SearchCriteria, bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration, bool? onlyMyItems, byte? OrderBy, bool? fromDateCheck, bool? toDateCheck, string fromDate, string toDate, int? page, int? displayMode, int? collectionId, int? statusId, string userId)
		{
			// Fill the view model
			var viewModel = fieldResults(SearchCriteria, typeAnaloog, typeDigitaal, typeVideoAnimation, typeMapIllustration, onlyMyItems, OrderBy, fromDateCheck, toDateCheck, fromDate, toDate, page, displayMode, collectionId, statusId, userId);

			return View(viewModel);
		}

		//
		// Create ViewModel based upon inputs
		//
		private SearchViewModel fieldResults(string SearchCriteria, bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration, bool? onlyMyItems, byte? OrderBy, bool? fromDateCheck, bool? toDateCheck, string fromDate, string toDate, int? page, int? displayMode, int? collectionId, int? statusId, string userId)
		{
			// Bypass check if dates should be taken into account for the search: this is 'true' by default
			if ((fromDate != null) && (toDate != null))
			{
				fromDateCheck = true;
				toDateCheck = true;
			}

			searchParameters searchParameters = new searchParameters() { SearchCriteria = SearchCriteria, displayMode = displayMode, fromDate = fromDate, fromDateCheck = fromDateCheck, toDate = toDate, toDateCheck = toDateCheck, OrderBy = OrderBy, page = page, typeAnaloog = typeAnaloog, typeDigitaal = typeDigitaal, typeVideoAnimation = typeVideoAnimation, typeMapIllustration = typeMapIllustration, onlyMyItems = onlyMyItems, collectionId = collectionId, statusId = statusId };
			TempData["resultSearchCriteria"] = searchParameters;

			string typeString = SetTypeString(typeAnaloog, typeDigitaal, typeVideoAnimation, typeMapIllustration);

			DateTime? from = null;
			if (fromDateCheck != null && !String.IsNullOrEmpty(fromDate))
				from = Convert.ToDateTime(fromDate);
			else
				from = Convert.ToDateTime("1-1-1900");

			DateTime? to = null;
			if (toDateCheck != null && !String.IsNullOrEmpty(toDate))
				to = Convert.ToDateTime(toDate);
			else
				to = DateTime.Now;

			// Default order by is on 'Datum aflopend'
			byte? orderBy = 7;
			if (OrderBy != null)
				orderBy = OrderBy;

			String searchString = "";
			if (!String.IsNullOrEmpty(SearchCriteria))
				searchString = SearchCriteria;

			int? selectedPage = 0;
			if (page != null)
				selectedPage = page;

			int? aantalRejected = 0;
			int? aantalNew = 0;
			int? aantalHidden = 0;
			int? aantalToPublish = 0;
			int? aantalInternal = 0;
			int? aantalExternal = 0;
			int? aantalNoThumbNail = 0;
			int? aantalNoMapNumber = 0;
            int? aantalNewUnknown = 0;
            int? aantalEditUnknown = 0;
			
			int? aantalResultaten = SetNrResults(displayMode);

			// User for edit rights and/or be able to see internal images
			MembershipUser currentUser = Membership.GetUser();
			bool switchContext = false;
			if ((userId != null) && (userId != "") && Roles.IsUserInRole("Administrator"))
			{
				// Current user is an Administrator and therefore allowed to switch context
				currentUser = Membership.GetUser(userId);
				switchContext = true;
			}
			String currentUserName = currentUser.UserName;
			String currentUserEmail = currentUser.Email;

			List<BEELDBANK_MEDIAOBJECT> Mediaobjects = null;
			List<StatusModel> StatusObjects = null;

			// Execute the stored procedure
			if (Roles.IsUserInRole("Administrator") && !switchContext)
			{
				IMultipleResults multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_ALSO_NON_VISIBLE(searchString, typeString, from, to, selectedPage, aantalResultaten, orderBy, collectionId, statusId, ref aantalResultaten);

				Mediaobjects = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT>().ToList();
				StatusObjects = multipleResults.GetResult<StatusModel>().ToList();
			}
			else
			{
				IMultipleResults multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_ALSO_NON_VISIBLE_BY_USERID(searchString, typeString, from, to, selectedPage, aantalResultaten, orderBy, collectionId, statusId, currentUserName, ref aantalResultaten);

				Mediaobjects = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT>().ToList();
				StatusObjects = multipleResults.GetResult<StatusModel>().ToList();
			}

			// Determine numbers
			foreach (var statusModel in StatusObjects)
			{
				switch (statusModel.StatusId)
				{
                    case Constants.ITEM_STATUS_EXTERN:
						aantalExternal = statusModel.Counter;
						break;
					case Constants.ITEM_STATUS_VERBORGEN:
						aantalHidden = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_NIEUW:
						aantalNew = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_INTERN:
						aantalInternal = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_PUBLISHABLE:
						aantalToPublish = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_REJECTED:
						aantalRejected = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_NO_PREVIEW:
						aantalNoThumbNail = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_NO_LOCATION:
						aantalNoMapNumber = statusModel.Counter;
						break;
                    case Constants.ITEM_STATUS_NEW_UNKNOWN:
                        aantalNewUnknown = statusModel.Counter;
                        break;
                    case Constants.ITEM_STATUS_EDIT_UNKNOWN:
                        aantalEditUnknown = statusModel.Counter;
                        break;
                }
			}

			// save all ID's of this search page to be able to navigate trough the results in detail mode
			String resultIdList = "";
			foreach (var mediaObject in Mediaobjects)
				resultIdList += mediaObject.Id + ",";

			TempData["resultIdList"] = resultIdList.TrimEnd(',');
			TempData["resultIdType"] = "Search";

			YearRepository yr = new YearRepository();

			// Fill the view model
			var viewModel = new SearchViewModel()
			{
				selectedCollectionId = collectionId,
				selectedStatusId = statusId,
				NumberOfResults = aantalResultaten.Value,
				mediaobjects = Mediaobjects.ToList(),
				currentUserName = currentUserName,
				currentUserEmail = currentUserEmail,

				TypeFacets = beeldBankDB.BEELDBANK_TYPEs.ToList(),
				YearFacets = yr.getDistinctYears(),
				ThemaFacets = beeldBankDB.BEELDBANK_COLLECTIONs.ToList(),
				RegioFacets = beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_REGIOs.ToList(),

				TypeFacetsAll = beeldBankDB.BEELDBANK_TYPEs.ToList(),
				YearFacetsAll = Tools.generateYearList(), // TODO: still have to generate a list of all years
				ThemaFacetsAll = beeldBankDB.BEELDBANK_COLLECTIONs.ToList(),
				RegioFacetsAll = beeldBankDB.BEELDBANK_MEDIAOBJECT_FACETS_REGIOs.ToList(),
			};
			viewModel.numberOfRejected = aantalRejected.Value;
			viewModel.numberOfHidden = aantalHidden.Value;
			viewModel.numberOfNew = aantalNew.Value;
			viewModel.numberOfPublishedExternal = aantalExternal.Value;
			viewModel.numberOfPublishedInternal = aantalInternal.Value;
			viewModel.numberOfReadyForPublish = aantalToPublish.Value;
			viewModel.numberOfNoMapNumber = aantalNoMapNumber.Value;
			viewModel.numberOfNoThumbNail = aantalNoThumbNail.Value;
            viewModel.numberOfNewUnknown = aantalNewUnknown.Value;
            viewModel.numberOfEditUnknown = aantalEditUnknown.Value;

			return viewModel;
		}

		[Authorize(Roles = "Administrator")]
		public ActionResult keyWordResults(string SearchCriteria, bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration, byte? OrderBy, bool? fromDateCheck, bool? toDateCheck, string fromDate, string toDate, int? page, int? displayMode, int? collectionId, int? statusId)
		{
			// Bypass check if dates should be taken into account for the search: this is 'true' by default
			if ((fromDate != null) && (toDate != null))
			{
				fromDateCheck = true;
				toDateCheck = true;
			}

			searchParameters searchParameters = new searchParameters() { SearchCriteria = SearchCriteria, displayMode = displayMode, fromDate = fromDate, fromDateCheck = fromDateCheck, toDate = toDate, toDateCheck = toDateCheck, OrderBy = OrderBy, page = page, typeAnaloog = typeAnaloog, typeDigitaal = typeDigitaal, typeVideoAnimation = typeVideoAnimation, typeMapIllustration = typeMapIllustration, collectionId = collectionId, statusId = statusId };
			TempData["resultSearchCriteria"] = searchParameters;

			string typeString = SetTypeString(typeAnaloog, typeDigitaal, typeVideoAnimation, typeMapIllustration);

			DateTime? from = null;
			if (fromDateCheck != null && !String.IsNullOrEmpty(fromDate))
				from = Convert.ToDateTime(fromDate);

			DateTime? to = null;
			if (toDateCheck != null && !String.IsNullOrEmpty(toDate))
				to = Convert.ToDateTime(toDate);

			// Default order by is on relevance
			byte? orderBy = 3;
			if (OrderBy != null)
				orderBy = OrderBy;

			String searchString = "";
			if (!String.IsNullOrEmpty(SearchCriteria))
				searchString = SearchCriteria;

			int? selectedPage = 0;
			if (page != null)
				selectedPage = page;

			int? aantalResultaten = SetNrResults(displayMode);

			int IDOnlyQuery = 0;
			Regex IDpattern = new Regex("ID[0-9]*\\Z");
			if (SearchCriteria != null && IDpattern.IsMatch(SearchCriteria))
			{
				IDOnlyQuery = 1;
				searchString = searchString.Substring(2, searchString.Length - 2);
			}
			
			// Rights section for different search results
			#region Rights section
			// User for edit rights and/or be able to see internal images
			MembershipUser currentUser = Membership.GetUser();
			String currentUserName = "";
			String currentUserEmail = "";

			bool? onlyMyItems = false;
			bool? showInternalItems = null;
			int? RegioFacet = 0;
			int? TechniekFacet = 0;
			int? RiviergebiedFacet = 0;
			int? ProjectFacet = 0;

			// User rights based search options
			int RWSonly = 0;
			string ShowMyItems = "";
			string ShowMyItemsID = "";
			int ShowAll = 0;
			if (currentUser != null)
			{
				currentUserName = currentUser.UserName;
				currentUserEmail = currentUser.Email;

				// @RWS.nl users get to see internal images
				if (currentUser.Email.EndsWith("@rws.nl") && showInternalItems != null && Convert.ToBoolean(showInternalItems) == true)
					RWSonly = 1;

				// Show only this persons items
				if (onlyMyItems != null && Convert.ToBoolean(onlyMyItems) == true)
				{
					if (Roles.IsUserInRole("Administrator"))
						ShowAll = 1;
					else
					{
						ShowMyItems = currentUser.UserName;
						ShowMyItemsID = userRepository.FindOnesGuidByName(currentUser.UserName).ToString();
					}
				}
			}
			#endregion

			// Get multiple results from search stored procedure
			#region Execute dynamic search stored procedure
			IMultipleResults multipleResults = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_DYNAMIC(searchString, typeString, from, to, selectedPage, aantalResultaten, orderBy, collectionId, statusId, ref aantalResultaten, @IDOnlyQuery, RWSonly, ShowAll, ShowMyItems, ShowMyItemsID, RegioFacet, TechniekFacet, RiviergebiedFacet, ProjectFacet);

			List<BEELDBANK_MEDIAOBJECT> Mediaobjects = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_REGIO> RegioFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_REGIO>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_TECHNIEK> TechniekFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_TECHNIEK>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_RIVIERGEBIED> RivierGebiedFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_RIVIERGEBIED>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_PROJECT> ProjectFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_PROJECT>().ToList();
			List<BEELDBANK_TYPE> TypeFacets = multipleResults.GetResult<BEELDBANK_TYPE>().ToList();
			List<BEELDBANK_MEDIAOBJECT_FACETS_RESULT> YearFacets = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_RESULT>().ToList();
			List<BEELDBANK_COLLECTION> ThemaFacets = multipleResults.GetResult<BEELDBANK_COLLECTION>().ToList();
			//List<BEELDBANK_MEDIAOBJECT_FACETS_RESULT> FacetsResults = multipleResults.GetResult<BEELDBANK_MEDIAOBJECT_FACETS_RESULT>().ToList();
			#endregion

			// save all ID's of this search page to be able to navigate trough the results in detail mode
			String resultIdList = "";
			foreach (var mediaObject in Mediaobjects)
				resultIdList += mediaObject.Id + ",";

			TempData["resultIdList"] = resultIdList.TrimEnd(',');
			TempData["resultIdType"] = "Search";

			// Fill the view model
			var viewModel = new SearchViewModel()
			{
				selectedCollectionId = collectionId,
				selectedStatusId = statusId,
				NumberOfResults = Convert.ToInt32(multipleResults.ReturnValue), //FacetsResults[0].results,
				mediaobjects = Mediaobjects.ToList(),
				currentUserName = currentUserName
			};

			return View(viewModel);
		}

		private int SetNrResults(int? displayMode)
		{
			if (displayMode != null)
			{
				switch (displayMode)
				{
					case 1:
						return 10;
					case 3:
						return 80;
					default:
						return 20;
				}
			}
			return 20;
		}

		private string SetTypeString(bool? typeAnaloog, bool? typeDigitaal, bool? typeVideoAnimation, bool? typeMapIllustration)
		{
			string typeString = "";

			if (typeAnaloog != null && typeAnaloog == true)
				typeString += "16 ";
			if (typeDigitaal != null && typeDigitaal == true)
				typeString += "19 ";
			if (typeVideoAnimation != null && typeVideoAnimation == true)
				typeString += "20 ";
			if (typeMapIllustration != null && typeMapIllustration == true)
				typeString += "24 ";
			// If no typeString is given a default must be passed or else
			// the stored procedure will run in an indefinite loop
			if (typeString == "")
				typeString = "16 19 20 24";

			return typeString;
		}

		public SimpleSearchViewModel simpleSearch(string SearchCriteria)
		{
			//USE [BeeldBankVenW]
			//GO

			//DECLARE	@return_value int,
			//        @RowsReturned int

			//EXEC	@return_value = [dbo].[BEELDBANK_CUSTOM_WORD_SEARCH]
			//        @SearchCriteria = N'water',
			//        @TypeList = N'16 19 20 24',
			//        @dtFrom = N'1900-1-1',
			//        @dtTo = N'2011-5-17',
			//        @PageIndex = 0,
			//        @PageSize = 20,
			//        @OrderBy = 6,
			//        @CollectionId = 0,
			//        @statusId = 11911
			//        @RowsReturned = @RowsReturned OUTPUT

			//SELECT	@RowsReturned as N'@RowsReturned'

			//SELECT	'Return Value' = @return_value

			//GO

			int? aantalResultaten = 0;

			DateTime? from = Convert.ToDateTime("1-1-1900");
			DateTime? to = Convert.ToDateTime("1-1-2020");

			List<BEELDBANK_MEDIAOBJECT> Mediaobjects = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH(SearchCriteria, "16 19 20 24", from, to, 0, 20, 6, 0, ref aantalResultaten).ToList();

			// Fill the results view model
			#region Fill results view model
			SimpleSearchViewModel viewModel = new SimpleSearchViewModel()
			{
				NumberOfResults = aantalResultaten.Value,
				mediaobjects = Mediaobjects.ToList(),
			};
			#endregion

			return viewModel;
		}

        public MetroSearchViewModel metroSimpleSearch(string SearchCriteria, int typeId, int page = 0)
        {
            //USE [BeeldBankVenW]
            //GO

            //DECLARE	@return_value int,
            //        @RowsReturned int

            //EXEC	@return_value = [dbo].[BEELDBANK_CUSTOM_WORD_SEARCH]
            //        @SearchCriteria = N'water',
            //        @TypeList = N'16 19 20 24',
            //        @dtFrom = N'1900-1-1',
            //        @dtTo = N'2011-5-17',
            //        @PageIndex = 0,
            //        @PageSize = 20,
            //        @OrderBy = 6,
            //        @CollectionId = 0,
            //        @statusId = 11911
            //        @RowsReturned = @RowsReturned OUTPUT

            //SELECT	@RowsReturned as N'@RowsReturned'

            //SELECT	'Return Value' = @return_value

            //GO

            int? aantalResultaten = 0;

            DateTime? from = Convert.ToDateTime("1-1-1900");
            DateTime? to = Convert.ToDateTime("1-1-2020");

            List<BeeldbankMediaObjectCollection> Mediaobjects = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_METRO_SIMPLE(SearchCriteria, typeId.ToString(), from, to, page, Constants.SEARCH_PAGE_SIZE, 6, null, ref aantalResultaten).ToList();

            // Fill the results view model
            #region Fill results view model
            MetroSearchViewModel viewModel = new MetroSearchViewModel()
            {
                NumberOfResults = aantalResultaten.Value,
                mediaobjectCollections = Mediaobjects.ToList(),
            };
            #endregion

            return viewModel;
        }


        public MetroSearchViewModel metroTopMediaList(string searchString, int typeId, int aantalResultaten, byte orderBy)
        {
            #region query and help
            // http://stackoverflow.com/questions/11285545/how-to-get-the-top-10-items-from-each-category
            //
			//WITH PartitionedComponents AS 
			//( 
			//    SELECT  
			//        CollectionID = c.ID,  
			//        CollectionName = c.Name,  
			//        CollectionDescription = c.Description, 
			//        MediaObjectId = m.ID, 
			//        m.Titel,
			//        m.Datum_Realisatie,
			//        m.Trefwoorden,
			//        m.Vervaardiger,
			//        ROW_NUMBER() OVER(PARTITION BY c.ID ORDER BY m.modifiedby DESC) AS 'RowNum' 
			//    FROM  
			//        dbo.BEELDBANK_COLLECTION c 
			//    INNER JOIN 
			//        dbo.BEELDBANK_MEDIAOBJECT_COLLECTION mc ON mc.CollectionId = c.ID 
			//    INNER JOIN 
			//        dbo.BEELDBANK_MEDIAOBJECT m ON mc.MediaObjectId = m.Id
            //    WHERE
            //        m.StatusId = 11911
            //    AND
            //        m.TypeId = @TypeId
			//) 
			//SELECT  
			//    CollectionID,  
			//    CollectionName,  
			//    CollectionDescription, 
			//    MediaObjectId,
			//    Titel,
			//    Datum_Realisatie,
			//    Trefwoorden,
			//    Vervaardiger
			//FROM  
			//    PartitionedComponents 
			//WHERE 
            //    RowNum <= @RowsReturned
            #endregion

            List<BeeldbankMediaObjectCollection> MediaobjectCollections = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_METRO_TOPMEDIA(searchString, typeId, aantalResultaten, orderBy).ToList();

			#region Fill results view model
            // Fill the results view model
            MetroSearchViewModel viewModel = new MetroSearchViewModel()
			{
				NumberOfResults = aantalResultaten,
                mediaobjectCollections = MediaobjectCollections.ToList(),
			};
			#endregion

			return viewModel;
		}

        public MetroSearchViewModel metroSearchMediaList(string searchString, int typeId, int aantalResultaten, byte orderBy)
        {
            List<BeeldbankMediaObjectCollection> MediaobjectCollections = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_METRO_MEDIA(searchString, typeId, aantalResultaten, orderBy).ToList();

            #region Fill results view model
            // Fill the results view model
            MetroSearchViewModel viewModel = new MetroSearchViewModel()
            {
                NumberOfResults = aantalResultaten,
                mediaobjectCollections = MediaobjectCollections.ToList(),
            };
            #endregion

            return viewModel;
        }

        [HttpPost]
        public JsonResult metroThemesList(int typeId)
        {
            CollectionRepository repository = new CollectionRepository();
            var result = repository.metroThemesList(typeId).ToList();

            return Json(result);
        }

        [HttpPost]
        public MetroSearchViewModel metroThemeMediaList(int collectionId, int typeId, int aantalResultaten, byte orderBy)
        {
            List<BeeldbankMediaObjectCollection> MediaobjectCollections = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_METRO_THEMEMEDIA(collectionId, typeId, aantalResultaten, orderBy).ToList();

            // Fill the results view model
            #region Fill results view model
            MetroSearchViewModel viewModel = new MetroSearchViewModel()
            {
                NumberOfResults = aantalResultaten,
                mediaobjectCollections = MediaobjectCollections.ToList(),
            };
            #endregion

            return viewModel;
        }

        [HttpPost]
        public MetroSearchViewModel metroNewMediaList(int aantalResultaten, byte orderBy, int typeId)
        {
            List<BeeldbankMediaObjectCollection> MediaobjectCollections = beeldBankDB.BEELDBANK_CUSTOM_WORD_SEARCH_METRO_NEWMEDIA(aantalResultaten, orderBy, typeId).ToList();

            // Fill the results view model
            #region Fill results view model
            MetroSearchViewModel viewModel = new MetroSearchViewModel()
            {
                NumberOfResults = aantalResultaten,
                mediaobjectCollections = MediaobjectCollections.ToList(),
            };
            #endregion

            return viewModel;
        }

        [HttpPost]
		public JsonResult FindKeyWords(string searchText, int maxResults)
		{
			KeyWordRepository repository = new KeyWordRepository();
			var result = repository.FindKeyWords(searchText, maxResults);
			
            return Json(result);
		}

		public ActionResult Deltar()
		{
			return View();
		}

        public ActionResult A2HO()
        {
            return View();
        }
    }
}
